package com.unc.allergyex.objects.tasks;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.os.AsyncTask;
import android.widget.Toast;

import com.unc.allergyex.Results;
import com.unc.allergyex.helpers.Deserializer;
import com.unc.allergyex.helpers.ObjManager;
import com.unc.allergyex.helpers.Service;
import com.unc.allergyex.objects.db.Restaurant;

/**This is an implementation of the android AsyncTask class.  It exists to 
 * spawn a separate thread to execute server queries.  This task is performed
 * in the doInBackground method.  The onPreExecute and onPostExecute methods 
 * are executed in the gui (main) thread of the given context; this is 
 * necessary because the gui library is not thread-safe.
 * @author Stephanie
 *
 */
public class MenuQueryTask extends AsyncTask<String, Void, Integer> {
	private Context context; //the context in which to execute the gui methods (draw the dialog)
	private ProgressDialog dialog; 
	private boolean cancelled;
	final String error = "Failed to acquire menu for selected restaurant from server."; // this is returned when the server fails

	public void onCancelled(){
		dialog.dismiss();
		cancelled = true;
	}
	
	/**This is a method to be called after creating the task to set the context.
	 * It is needed because the context must already be set before execute is called, 
	 * so that the preexecute method will have access to the context.
	 * @param context the context in which to post notifications
	 */
	public void setContext(Context context){
		this.context = context;
		cancelled = false;
	}
	
	/**A call to .execute() will call this method. The parameter is the string id 
	 * of the restaurant to be queried. This method uses the service class to do the actual query and
	 * uses the Deserializer to deserialize the menu into the ObjManager.
	 * @see android.os.AsyncTask#doInBackground(Params[])
	 */
	@Override
	protected Integer doInBackground(String... p) {
		String id = p[0];
		Restaurant currentRestaurant = ObjManager.getRestaurant();
		if (currentRestaurant != null && currentRestaurant.getId().equals(id)){
			return 0;
		}
		Service service = new Service(context);
		String menuJSON;
		try {
			menuJSON = service.unambiguousIdQuery(id);
			if (cancelled == false){
				Deserializer.deserializeMenu(menuJSON);
			}
			return 0;
		} catch (Exception e){
			return 1;
		}
	}

	/**This method is called when execute() is called before doInBackground is called.
	 * The ProgressDialog is drawn in the main thread of the given context.
	 * The dialog does not allow any user interaction.
	 * @see android.os.AsyncTask#onPreExecute()
	 */
	protected void onPreExecute(){
		dialog = new ProgressDialog(context);
        dialog.setMessage("Om nom nom...");
        dialog.setIndeterminate(true);
        dialog.setCancelable(true);
        final MenuQueryTask task = this;
        dialog.setOnCancelListener( new OnCancelListener(){
			@Override
			public void onCancel(DialogInterface arg0) {
				task.cancel(true);
			}
        });
        dialog.show();
	}

	/**This method is called when execute() is called after doInBackground returns.
	 * This dialog is dismissed, and the results activity is launched.
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	protected void onPostExecute(Integer i){
		if (cancelled == false){
			dialog.dismiss();
			if (i == 0){
				Intent intent = new Intent(context, Results.class);
				context.startActivity(intent);
			}
			else {
				toast(error);
			}
		}
	}
	
	/**This is a helper method used to make toasts.
	 * @param message the string to toast
	 */
	protected void toast(String message){
		Toast.makeText(context, message, Toast.LENGTH_LONG).show();
	}
}